using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
using _404park.Utilities.Extensions;
using _404park.Core.Crawler;

namespace _404park.ApplicationServices.Crawler.Parser.Provider
{
	public class TwitterParser : BaseFeedParser
	{
		public override string BaseUrl
		{
			get { return "http://search.twitter.com/search.atom?q={0}&count=10&page={1}"; }
		}

        internal override string GetFeedUrl(string keyword, int start = 0)
        {
            return string.Format(BaseUrl, keyword, start + 1);
        }

		protected internal override IList<Feed> ParseFeed(string data)
		{
			var feedList = new List<Feed>();
			var xmlDoc = XDocument.Parse(data);
			var defaultNameSpace = xmlDoc.Root.GetDefaultNamespace();
			if (xmlDoc.Root != null)
			{
				xmlDoc.Root.Descendants(defaultNameSpace + "entry").ToList().ForEach(element => feedList.Add(CreateFeedItem(element, defaultNameSpace)));
			}
			return feedList;
		}

		#region Private methods

		private Feed CreateFeedItem(XElement xElement, XNamespace defaultNameSpace)
		{
			var author_name = string.Empty;
			var author_uri = string.Empty;
			var click_url = string.Empty;
			var display_url = string.Empty;

			var title = Decode(xElement.Element(defaultNameSpace + "title") != null ? xElement.Element(defaultNameSpace + "title").Value : string.Empty);
			var published = xElement.Element(defaultNameSpace + "published") != null ? xElement.Element(defaultNameSpace + "published").Value : string.Empty;
			var content = xElement.Element(defaultNameSpace + "content") != null ? xElement.Element(defaultNameSpace + "content").ReadInnerTags() : string.Empty;

			XElement authorElement = xElement.Element(defaultNameSpace + "author");
			if (authorElement != null)
			{
				author_name = authorElement.Element(defaultNameSpace + "name") != null ? authorElement.Element(defaultNameSpace + "name").Value : string.Empty;
				author_uri = authorElement.Element(defaultNameSpace + "uri") != null ? authorElement.Element(defaultNameSpace + "uri").Value : string.Empty;
			}

			xElement.Elements(defaultNameSpace + "link").ToList().ForEach(link =>
			                                                              {
				click_url = link.Attribute("type") != null && link.Attribute("type").Value.Equals("text/html") ? click_url = link.Attribute("href").Value : click_url;
				display_url = link.Attribute("type") != null && link.Attribute("type").Value.Equals("image/png") ? display_url = link.Attribute("href").Value : display_url;
			});

			var feed = new TwitterFeed
			{
				Title = Decode(title),
				Description = BuildDescription(published, content, author_uri, author_name),
				ClickUrl = Decode(click_url),
				DisplayUrl = Decode(display_url),
				Author = BuildAuthorLink(author_name, author_uri),
				Published = Decode(published)
			};
			return feed;
		}

		private string Decode(string target)
		{
			return StringExtensions.HtmlDecode(target);
		}

		private string BuildAuthorLink(string author_name, string author_uri)
		{
			return string.Format("<a href='{0}'>{1}</a>", author_uri, author_name);
		}

		private string BuildDescription(string published, string content_type, string author_uri, string author_name)
		{
			return string.Format("Published: {0}<br/>{1}<br/>Author: <a href='{2}'>{3}</a>",
			                     published,
			                     content_type,
			                     author_uri,
			                     author_name).Replace('"', '\'');
		}

		#endregion
	}

	[Serializable]
	public class TwitterFeed : Feed
	{
		public string Published
		{
			get;
			set;
		}
		private string author;

		public string Author
		{
			get;
			set;
		}
	}
}

